package main

/*
* Content: json包-序列化、json tag
* --------------------------------------------------
* Go语言json包的使用技巧: https://juejin.cn/post/6945023713930641445
 */

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

// 定义结构体Tag
type book2 struct {
	title string `name:"xqz:18;wss:17" hobby:"dance"`
	page  int
}

func MyBagJson() {

	// json包-序列化
	fmt.Println("--------------------json包-序列化--------------------")

	// 初始化结构体
	p1 := Person{
		Name: "谢清照",
		Age:  18,
	}
	fmt.Printf("未进行序列化的数据p1: %#v\n", p1)

	// 序列化: struct -> json string
	b, err := json.Marshal(p1)
	if err != nil {
		fmt.Printf("json.Marshal failed, err: %v\n", err)
		return
	}
	fmt.Printf("p1序列化后的数据: %s\n", b)

	// 反序列化: json string -> struct
	var p2 Person
	err = json.Unmarshal(b, &p2)
	if err != nil {
		fmt.Printf("json.Unmarshal failed, err: %v\n", err)
		return
	}
	fmt.Printf("反序列化出的数据p2: %#v\n", p2)

	// json string 转 map
	fmt.Println("--------------------json string 转 map--------------------")

	var m map[string]interface{}
	err = json.Unmarshal(b, &m)
	if err != nil {
		fmt.Printf("json.Unmarshal failed, err: %v\n", err)
		return
	}
	fmt.Printf("反序列化到map中的的数据m: %#v\n", m)

	// json tag
	fmt.Println("--------------------json tag--------------------")
	// 序列化 与 反序列化 默认情况下使用结构体的 字段名，我们可以通过给结构体字段添加 tag 来指定 json序列化 生成的字段名。

	// 初始化结构体
	myBook := book2{
		title: "Java",
		page:  819,
	}

	// 获取结构体类型
	typeBook := reflect.TypeOf(myBook)

	// 获取结构体 tag
	myTag, _ := typeBook.FieldByName("title")
	fmt.Printf("获取到的tag信息: %v\n", myTag)

	// 获取 key 对应的 Tag
	value, ok := myTag.Tag.Lookup("name")
	if ok {
		fmt.Printf("name对应的Tag为: %s\n", value) // "xqz:18;wss:17"
	} else {
		fmt.Println("没有获取到对应的Tag！")
	}

}
